#ifndef MANIPULATION_CASES_H
#   define MANIPULATION_CASES_H


#include "cases.h"
#include "carte_zone.h"


/**
 * \fn void init_tab_dyn_cases_constantes(struct tab_dyn_cases_constantes* tab, const unsigned int taille)
 * \brief Initialise un tab_dyn_cases_constantes pour qu'il soit pret a accueillir des elements
 *
 * \param[out] tab Un pointeur vers le tableau a initialiser
 * \param[in] taille Le nombre de cases qu'aura le tableau
 */
void init_tab_dyn_cases_constantes(struct tab_dyn_cases_constantes* tab, const unsigned int taille);




/**
 * \fn void ajouter_case_constante(struct tab_dyn_cases_constantes* tab, const struct case_constante* type_case_constante)
 * \brief Ajoute un type de case constante a la liste contenue dans carte_zone
 *
 * \param[in,out] tab Un pointeur vers le tab_dyn_cases_constantes a modifier
 * \param[in] type_case_constante Un pointeur vers le type de case constante que l'on souhaite ajouter
 */
void ajouter_case_constante(struct tab_dyn_cases_constantes* tab, const struct case_constante* type_case_constante);



/**
 * \fn void detruire_tab_dyn_cases_constantes(struct tab_dyn_cases_constantes* tab)
 * \brief Libere la memoire allouee pour un tab_dyn_cases_constantes
 *
 * \param tab Le tableau a detruire
 */
void detruire_tab_dyn_cases_constantes(struct tab_dyn_cases_constantes* tab);



/**
 * \fn struct case_constante* get_case_constante_liste_types(const struct carte_zone* carte, const unsigned char n)
 * \brief Obtient le type de case constante d'indice n dans une carte_zone
 *
 * \param[in] carte Un pointeur vers la carte a laquelle on s'interesse
 * \param[in] n L'indice du type de case que l'on souhaite obtenir
 * \return Un pointeur vers le type de case constante recherche
 */
struct case_constante* get_case_constante_liste_types(const struct carte_zone* carte, const unsigned char n);



/**
 * \fn void set_case_constante_grille(struct carte_zone* carte, const unsigned char type_case,
                                      const unsigned int x, const unsigned int y)
 * \brief Met un certain type de case dans la grille de cases constantes d'une carte_zone
 *
 * \param[out] carte Un pointeur vers la carte_zone a alterer
 * \param[in] type_case Un pointeur vers le type de case que l'on veut introduire dans la grille
 * \param[in] x Coordonnee horizontale de la case a modifier (min 0)
 * \param[in] y Coordonnee verticale de la case a modifier (min 0)
 */
void set_case_constante_grille(struct carte_zone* carte, const unsigned char type_case,
                               const unsigned int x, const unsigned int y);



/**
 * \fn struct case_constante* get_case_constante_grille(const struct carte_zone* carte,
                                                 const unsigned int x, const unsigned int y)
 * \brief Donne les caracteristiques de la case constante
situee a un emplacement donne dans la grille de cases
constantes d'une carte de zone
 *
 * \param[in] carte Un pointeur vers la carte a laquelle on s'interesse
 * \param[in] x La coordonnee horizontale de la case a laquelle on s'interesse (0..largeur - 1)
 * \param[in] y La coordonnee verticale de la case a laquelle on s'interesse (0..hauteur - 1)
 * \return Un pointeur vers les caracteristiques de la case constante concernee
 */
struct case_constante* get_case_constante_grille(const struct carte_zone* carte,
                                                 const unsigned int x, const unsigned int y);




/**
 * \fn void remplir_rectangle_cases_constantes(struct carte_zone* carte, unsigned char type_case,
                                               const unsigned int x_min, const unsigned int y_min,
                                               const unsigned int x_max, const unsigned int y_max)
 * \brief Remplit un rectangle dont les coordonnees sont donnees avec un type
 *        de case donne dans la grille de cases constantes d'une carte_zone
 *
 * \param[in,out] carte Un pointeur vers la carte concernee
 * \param[in] type_case Un pointeur vers le type de case que l'on veut utiliser
 * \param[in] x_min Coordonne horizontale minimale du rectangle
 * \param[in] y_min Coordonne verticale minimale du rectangle
 * \param[in] x_max Coordonne horizontale maximale du rectangle
 * \param[in] y_max Coordonne verticale maximale du rectangle
 *
 * Cette fonction peut tracer un rectangle meme si ses coordonnees minimales
 * et maximales sont echangees, mais il vaut mieux les lui donner dans le
 * bon ordre. Coordonnees : de 0 a taille - 1 inclus.
 */
void remplir_rectangle_cases_constantes(struct carte_zone* carte, unsigned char type_case,
                                        const unsigned int x_min, const unsigned int y_min,
                                        const unsigned int x_max, const unsigned int y_max);




/**
 * \fn void set_case_destructible_grille(struct carte_zone* carte, const struct case_destructible* donnees_case,
                                  const unsigned int x, const unsigned int y)
 * \brief met un element destructible dans la grille d'elements destructibles d'une carte_zone
 *
 * \param[out] carte Un pointeur vers la carte concernee
 * \param[in] donnees_case Un pointeur vers le type d'element a ajouter
 * \param[in] x Coordonnee horizontale de la case a modifier (min 0)
 * \param[in] y Coordonnee verticale de la case a modifier (min 0)
 *
 * \warning Cette fonction est aussi utilisee pour mettre la valeur NULL dans
 *          la grille.\n
 *          Si donnees_case vaut NULL, c'est ce qui se passera. Sinon, la
 *          case sera remplie avec les donnees de donnees_case.\n
 *          Notez bien que, dans le premier cas, aucun free n'est fait.
 *          Soyez vigilant lors du remplacement du contenu d'une case !
 */
void set_case_destructible_grille(struct carte_zone* carte, const struct case_destructible* donnees_case,
                                  const unsigned int x, const unsigned int y);




/**
 * \fn void remplir_rectangle_cases_destructibles(struct carte_zone* carte, const struct case_destructible* donnees_case,
                                                  const unsigned int x_min, const unsigned int y_min,
                                                  const unsigned int x_max, const unsigned int y_max)
 * \brief Remplit un rectangle dont les coordonnees sont donnees avec un type
de case donne dans la grille de cases indestructibles d'une carte_zone
 *
 * \param[out] carte Un pointeur vers la carte concernee
 * \param[in] donnees_case Un pointeur vers le type de case que l'on veut utiliser
 * \param[in] x_min Coordonne horizontale minimale du rectangle
 * \param[in] y_min Coordonne verticale minimale du rectangle
 * \param[in] x_max Coordonne horizontale maximale du rectangle
 * \param[in] y_max Coordonne verticale maximale du rectangle
 *
 * Cette fonction peut tracer un rectangle meme si ses coordonnees minimales
 * et maximales sont echangees, mais il vaut mieux les lui donner dans le
 * bon ordre. Coordonnees : de 0 a taille - 1 inclus.
 */
void remplir_rectangle_cases_destructibles(struct carte_zone* carte, const struct case_destructible* donnees_case,
                                           const unsigned int x_min, const unsigned int y_min,
                                           const unsigned int x_max, const unsigned int y_max);





/**
 * \fn struct case_destructible* get_case_destructible(const struct carte_zone* carte,
                                                       const unsigned int x, const unsigned int y)
 * \brief Obtient l'adresse d'une case destructible donnee (NULL si la
case concernee ne contient pas d'element destructible)
 *
 * \param[in] carte Un pointeur vers la carte concernee
 * \param[in] x La coordonnee horizontale de la case a laquelle on s'interesse (0..largeur - 1)
 * \param[in] y La coordonnee verticale de la case a laquelle on s'interesse (0..hauteur - 1)
 * \return Un pointeur vers les caracteristiques de l'element
trouve. NULL si aucun element trouve
 */
struct case_destructible* get_case_destructible(const struct carte_zone* carte,
                                                const unsigned int x, const unsigned int y);


/**
 * \fn void endommager_case_destructible(struct carte_zone* carte, unsigned int x, unsigned int y)
 * \brief Enleve un point de vie a un element destructible et le supprime si necessaire
 *
 * \param[in,out] carte L'adresse d'une carte de zone
 * \param[in] x Coordonnee horizontale de la case affectee
 * \param[in] y Coordonnee verticale de la case affectee
 *
 * Rappel : chaque rencontre d'un projectile avec un element destructible lui
 * enleve 1 point de vie, quel que soit la puissance du projectile.\n
 * Un element est detruit si ses points de vie atteignent 0.\n
 * Lorsqu'un element est detruit, tous les elements du meme groupe sont
 * egalement detruits. Le numero de groupe 0 indique un degroupage : les
 * elements sont alors independants.
 */
void endommager_case_destructible(struct carte_zone* carte, unsigned int x, unsigned int y);



/**
 * \fn void detruire_cases_groupe(struct carte_zone* carte, const unsigned int num_groupe)
 * \brief Detruit toutes les cases destructibles d'un groupe donne
 *
 * \param[in,out] carte L'adresse de la carte de la zone concernee
 * \param[in] num_groupe Le numero du groupe a eradiquer
 */
void detruire_cases_groupe(struct carte_zone* carte, const unsigned int num_groupe);






#endif /* MANIPULATION_CASES_H */
